package com.cjd.common.service;

import android.annotation.SuppressLint;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Environment;
import android.os.IBinder;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import androidx.core.content.FileProvider;

import com.cjd.common.R;
import com.cjd.common.utils.LogUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.DecimalFormat;

/**
 * Created by ChenJiDong on 2016/11/2.
 * <uses-permission android:name="android.permission.INTERNET" />
 * <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 * <uses-permission android:name="android.permission.VIBRATE" />
 * <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
 */

public class DownloadAPKService extends Service {
    public static final String DOWNLOAD_URL_KEY = "download_url_key";
    public static final String FILE_PROVIDER_KEY = "file_provider";

    private final int notificationID = 0x10000;
    private NotificationManager mNotificationManager = null;
    private NotificationCompat.Builder builder;

    private final static int DOWNLOAD_COMPLETE = 1;// 完成
    private final static int DOWNLOAD_FAIL = -2;// 失败
    // BT字节参考量
    private static final float SIZE_BT = 1024L;
    // KB字节参考量
    private static final float SIZE_KB = SIZE_BT * 1024.0f;
    // MB字节参考量
    private static final float SIZE_MB = SIZE_KB * 1024.0f;

    File apkFile;
    // 文件下载路径
    private String apkUrl = "";
    private String fileProvider = "";

    /**
     * 启动服务下载
     * tips:多渠道需要调整
     *
     * @param context 上下文
     * @param url     完整下载地址
     */
    public static void startDownload(Context context, String url) {
        String provider = context.getPackageName() + ".fileProvider";
        Intent intent = new Intent(context, DownloadAPKService.class);
        intent.putExtra(DownloadAPKService.DOWNLOAD_URL_KEY, url);
        intent.putExtra(DownloadAPKService.FILE_PROVIDER_KEY, provider);
        context.startService(intent);
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        init();// 创建保存路径
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        apkUrl = intent.getStringExtra(DOWNLOAD_URL_KEY);
        fileProvider = intent.getStringExtra(FILE_PROVIDER_KEY);
        DownFile();
        return super.onStartCommand(intent, flags, startId);
    }

    private void init() {
        String path;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            path = getApplicationContext().getFilesDir().getAbsolutePath() + "/download/";// 保存到app的包名路径下
        } else {
            if (isHasSdcard())
                path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/download/";// 保存到SD卡路径下
            else {
                throw new RuntimeException("please get android.permission.WRITE_EXTERNAL_STORAGE！");
            }
        }
        apkFile = new File(path + getApplicationName() + ".apk");

        if (apkFile.getParentFile() != null && !apkFile.getParentFile().exists()) {// 判断文件夹是否存在
            apkFile.getParentFile().mkdirs();
        }

        mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        builder = new NotificationCompat.Builder(getApplicationContext());
        builder.setSmallIcon(R.drawable.base_ic_launcher);
        builder.setTicker("正在下载新版本");
        builder.setContentTitle(getApplicationName());
        builder.setContentText("正在下载,请稍后...");
        builder.setNumber(0);
        builder.setAutoCancel(true);
        mNotificationManager.notify(notificationID, builder.build());
    }

    /**
     * 判断是否插入SD卡
     */
    private boolean isHasSdcard() {
        String status = Environment.getExternalStorageState();
        return status.equals(Environment.MEDIA_MOUNTED);
    }

    private void DownFile() {
        new UpdateThread().execute();
    }

    /**
     * 获取当前应用的名称
     */
    private String getApplicationName() {
        PackageManager packageManager = null;
        ApplicationInfo applicationInfo;
        try {
            packageManager = getApplicationContext().getPackageManager();
            applicationInfo = packageManager.getApplicationInfo(getPackageName(), 0);
        } catch (PackageManager.NameNotFoundException e) {
            applicationInfo = null;
        }
        return (String) packageManager.getApplicationLabel(applicationInfo);
    }


    @Override
    public void onDestroy() {
        super.onDestroy();
        stopSelf();
    }


    private void disposeResult() {
        Intent installIntent = new Intent(Intent.ACTION_VIEW);
        Uri uri;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            uri = FileProvider.getUriForFile(this, fileProvider, apkFile);
            installIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        } else {
            uri = Uri.fromFile(apkFile);
            installIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        }
        installIntent.setDataAndType(uri, "application/vnd.android.package-archive");
        PendingIntent mPendingIntent = PendingIntent.getActivity(DownloadAPKService.this, 0, installIntent, 0);
        builder.setContentText("下载完成,请点击安装");
        builder.setContentIntent(mPendingIntent);
        mNotificationManager.notify(notificationID, builder.build());
//                     震动提示
//        Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
//        vibrator.vibrate(1000L);// 参数是震动时间(long类型)
        stopSelf();
        startActivity(installIntent);// 下载完成之后自动弹出安装界面
        mNotificationManager.cancel(notificationID);
    }

    /**
     * 下载更新程序文件
     *
     * @param downloadUrl 下载地址
     * @return
     */
    private int downloadUpdateFile(String downloadUrl) {
        int count = 0;
        long totalSize = 0;   //总大小
        long downloadSize = 0;   //下载的大小
        URL url;
        InputStream inputStream = null;
        FileOutputStream fos = null;
        HttpURLConnection httpConn = null;
        try {
            url = new URL(downloadUrl);
            httpConn = (HttpURLConnection) url.openConnection();

            int statusCode = httpConn.getResponseCode();
            switch (statusCode) {
                case 200:
                    inputStream = httpConn.getInputStream();
                    if (inputStream != null) {
                        totalSize = httpConn.getContentLength();
                        LogUtils.d(apkFile.getAbsolutePath());
                        fos = new FileOutputStream(apkFile, false);
                        byte buffer[] = new byte[1024];
                        int readSize = 0;
                        while ((readSize = inputStream.read(buffer)) > 0) {
                            fos.write(buffer, 0, readSize);
                            downloadSize += readSize;
                            if ((count == 0) || (int) (downloadSize * 100 / totalSize) >= count) {
                                count += 5;
                                builder.setProgress(100, (int) (((float) downloadSize / totalSize) * 100), false);
                                builder.setContentInfo(getMsgSpeed(downloadSize, totalSize));
                                mNotificationManager.notify(notificationID, builder.build());
                            }
                        }
                        fos.flush();
                        if (totalSize >= downloadSize) {
                            return DOWNLOAD_COMPLETE;
                        } else {
                            return DOWNLOAD_FAIL;
                        }
                    }
                    break;
                default:
                    break;
            }
        } catch (Exception e) {
            LogUtils.e(e);
        } finally {
            try {
                if (fos != null) {
                    fos.close();
                }
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (httpConn != null) {
                httpConn.disconnect();
            }
        }
        return DOWNLOAD_FAIL;
    }

    /**
     * 获取下载进度
     */
    public static String getMsgSpeed(long downSize, long allSize) {
        StringBuffer sBuf = new StringBuffer();
        sBuf.append(getSize(downSize));
        sBuf.append("/");
        sBuf.append(getSize(allSize));
        sBuf.append(" ");
        sBuf.append(getPercentSize(downSize, allSize));
        return sBuf.toString();
    }

    /**
     * 获取大小
     *
     * @param size
     * @return String
     */
    public static String getSize(long size) {
        if (size >= 0 && size < SIZE_BT) {
            return (double) (Math.round(size * 10) / 10.0) + "B";
        } else if (size >= SIZE_BT && size < SIZE_KB) {
            return (double) (Math.round((size / SIZE_BT) * 10) / 10.0) + "KB";
        } else if (size >= SIZE_KB && size < SIZE_MB) {
            return (double) (Math.round((size / SIZE_KB) * 10) / 10.0) + "MB";
        }
        return "";
    }

    /**
     * 获取到当前的下载百分比
     *
     * @param downSize 下载大小
     * @param allSize  总共大小
     */
    public static String getPercentSize(long downSize, long allSize) {
        String percent = (allSize == 0 ? "0.0" : new DecimalFormat("0.0")
                .format((double) downSize / (double) allSize * 100));
        return "(" + percent + "%)";
    }


    @SuppressLint("StaticFieldLeak")
    private class UpdateThread extends AsyncTask<String, Integer, Integer> {

        @Override
        protected Integer doInBackground(String... params) {
            return downloadUpdateFile(apkUrl);
        }

        @Override
        protected void onPostExecute(Integer result) {
            super.onPostExecute(result);

            switch (result) {
                case DOWNLOAD_COMPLETE:
                    disposeResult();
                    break;
                case DOWNLOAD_FAIL:
                    mNotificationManager.cancel(notificationID);
                    Toast.makeText(getApplicationContext(), "下载失败，请检查网络！！！", Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    }
}
